<?php

/*
 * Copyright (C) 2009 - 2011 Pham Cong Dinh
 *
 * This file is part of Spica.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 3 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

/**
 * <p>Set of methods to support format conversion manipulation.</p>
 *
 * namespace spica\core\utils
 *
 * @category   spica
 * @package    core
 * @subpackage utils
 * @author     Pham Cong Dinh <pcdinh at phpvietnam dot net>
 * @since      Version 0.3
 * @since      May 03, 2009
 * @copyright  Pham Cong Dinh (http://www.phpvietnam.net)
 * @license    http://www.gnu.org/licenses/lgpl-3.0.txt
 * @version    $Id: FormatUtils.php 1869 2011-01-07 18:55:25Z pcdinh $
 */
class SpicaFormatUtils
{
    /**
     * Converts an array to XML format representation.
     *
     * Ported from PONE framework.
     *
     * @see    SpicaMySQLResultSet::getAssociativeArray()
     * @param  array  $array       The original array
     * @param  string $numericNode Tag to use when a numberic array key is encountered
     * @param  string $topNode     The top node
     * @param  int    $level       The position of the keys of the array in relative to XML top nodes. Top nodes will be translated to $level = 1
     * @param  string $docType
     * @return string
     */
    public static function arrayToXml($array, $numericKeyNode = 'value', $topNode = 'root', $level = 1, $docType = '')
    {
        $xml = '';
        $spaces = 4;
        $indented = str_repeat(' ', $level * $spaces);

        foreach ($array as $key => $value)
        {
            if (true === is_object($value))
            {
                $value = (array) $value;
            }

            if (true === is_array($value))
            {
                if (true === is_numeric($key))
                {
                    $xml .= $indented . '<' . $numericKeyNode . ' key="' . $key . '">' . "\n";
                    $key = $numericKeyNode;
                }
                else
                {
                    $xml .= $indented . '<' . $key . ">\n";
                }

                // Recursive calls
                $xml .= self::arrayToXml($value, $numericKeyNode, $topNode, $level + 1);
                $xml .= $indented . '</' . $key . ">\n";
            }
            elseif (true === is_numeric($key))
            {
                $value = self::wrapCdata($value);
                $xml .= $indented . '<' . $numericKeyNode . ' key="' . $key . '">' . $value . '</' . $numericKeyNode . ">\n";
            }
            else
            {
                $value = self::wrapCdata($value);
                $xml .= $indented . "<$key>$value</$key>\n";
            }
        }

        $prefix = '';
        $suffix = '';

        if (1 === $level)
        {
            $prefix = '<?xml version="1.0" encoding="UTF-8"?>' . "\n" . $docType . "\n<" . $topNode . ">\n";
            $suffix = '</' . $topNode . '>';
        }

        return $prefix . $xml . $suffix;
    }

    /**
     * Converts an object to an array.
     *
     * Ported from PONE framework.
     *
     * @param  object $object
     * @param  array $resultArray
     * @return array
     */
    public static function objectToArray($object, & $resultArray)
    {
        if (true === is_object($object))
        {
            foreach ($object as $key => $value)
            {
                self::objectToArray($value, $resultArray[$key]);
            }
        }
        elseif (true === is_array($object))
        {
            foreach ($object as $key => $value)
            {
                self::objectToArray($value, $resultArray[$key]);
            }
        }
        else
        {
            $resultArray = $object;
        }

        return $resultArray;
    }

    /**
     * Encodes a string to be include in XML tags.
     *
     * To use only if the 'quoteContents' is false
     * Convert :  &      <     >     "       '
     *      To :  &amp;  &lt;  &gt;  &quot;  &apos;
     *
     * Ported from PONE framework.
     *
     * @param  string $content Content to be quoted
     * @return string          The quoted content
     */
    public static function quoteCdata($content)
    {
        return str_replace(array('&', '<', '>', '"', "'"), array('&amp;', '&lt;', '&gt;', '&quot;', '&apos;'), $content);
    }

    /**
     * Wraps a string that contains "<" or "&" characters in a CDATA section.
     *
     * To use only if the 'quoteContents' is false
     * Convert :  &      <     >     "       '
     *      To :  &amp;  &lt;  &gt;  &quot;  &apos;
     *
     * Ported from PONE framework.
     *
     * @param  string $content Content to be quoted
     * @return string          The quoted content
     */
    public static function wrapCdata($content)
    {
        if (true === empty($content))
        {
            return '';
        }

        if (true === is_numeric($content))
        {
            return $content;
        }

        $content2 = str_replace(array('&', '<', '>', '"', "'", ']]>'),
            array('&amp;', '&lt;', '&gt;', '&quot;', '&apos;', "\]\]\>"),
            $content);

        if ($content2 !== $content)
        {
            return '<![CDATA[' . $content . ']]>';
        }

        return $content;
    }
}

?>